import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;

public class RsaDec {

    public static byte[] decrypt(byte[] byteDatas, String privateKeyStr) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKeyStr);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int inputLen = byteDatas.length;
        int offSet = 0;
        byte[] cache;
        int i = 0;

        while (inputLen - offSet > 0) {
            if (inputLen - offSet > 128) {
                cache = cipher.doFinal(byteDatas, offSet, 128);
            } else {
                cache = cipher.doFinal(byteDatas, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * 128;
        }

        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    public static void main(String[] args) {
        File sourceFile = new File(args[0]);
        File targetFile = new File(args[1]);
        File privateKeyFile = new File(args[2]);

        try {
            String privateKey =
                FileUtils.readFileToString(privateKeyFile).replaceAll("\\s", "").replaceAll("---+[a-zA-Z]+---+", "");
            byte[] bytes = decrypt(FileUtils.readFileToByteArray(sourceFile), privateKey);
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            FileUtils.copyInputStreamToFile(in, targetFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

